﻿using System.Configuration;

namespace NBuild.Fx.Engine
{
    internal sealed class NBuildSection : ConfigurationSection
    {
        [ConfigurationProperty(ConfigProperty_Language, DefaultValue = "cs")]
        public string Language
        {
            get { return (string)this[ConfigProperty_Language]; }
            set { this[ConfigProperty_Language] = value; }
        }

        [ConfigurationCollection(typeof(NBuildReferenceElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
        [ConfigurationProperty(ConfigElement_References)]
        public NBuildReferenceElementCollection References
        {
            get { return this[ConfigElement_References] as NBuildReferenceElementCollection; }
            set { this[ConfigElement_References] = value; }
        }

        [ConfigurationCollection(typeof(NBuildReferencePathElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
        [ConfigurationProperty(ConfigElement_ReferencePaths)]
        public NBuildReferencePathElementCollection ReferencePaths
        {
            get { return this[ConfigElement_ReferencePaths] as NBuildReferencePathElementCollection; }
            set { this[ConfigElement_ReferencePaths] = value; }
        }

        internal const string SectionPath = "nbuild";
        private const string ConfigProperty_Language = "language";
        private const string ConfigElement_References = "references";
        private const string ConfigElement_ReferencePaths = "referencePaths";
    }

    [ConfigurationCollection(typeof(NBuildReferenceElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
    internal sealed class NBuildReferenceElementCollection : ConfigurationElementCollection
    {
        internal NBuildReferenceElement[] ToArray()
        {
            if (Count == 0)
                return new NBuildReferenceElement[0];
            var referencePaths = new NBuildReferenceElement[Count];
            CopyTo(referencePaths, 0);
            return referencePaths;
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new NBuildReferenceElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((NBuildReferenceElement)element).File;
        }
    }

    internal sealed class NBuildReferenceElement : ConfigurationElement
    {
        [ConfigurationProperty(ConfigProperty_File, IsKey = true, IsRequired = true)]
        public string File
        {
            get { return (string)this[ConfigProperty_File]; }
            set { this[ConfigProperty_File] = value; }
        }

        private const string ConfigProperty_File = "file";
    }

    [ConfigurationCollection(typeof(NBuildReferencePathElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
    internal sealed class NBuildReferencePathElementCollection : ConfigurationElementCollection
    {
        internal NBuildReferencePathElement[] ToArray()
        {
            if (Count == 0)
                return new NBuildReferencePathElement[0];
            var references = new NBuildReferencePathElement[Count];
            CopyTo(references, 0);
            return references;
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new NBuildReferencePathElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((NBuildReferencePathElement)element).Path;
        }
    }

    internal sealed class NBuildReferencePathElement : ConfigurationElement
    {
        [ConfigurationProperty(ConfigProperty_Path, IsKey = true, IsRequired = true)]
        public string Path
        {
            get { return (string)this[ConfigProperty_Path]; }
            set { this[ConfigProperty_Path] = value; }
        }

        private const string ConfigProperty_Path = "path";
    }
}
